package com.gateway.config;


import com.common.properties.SecurityProperties;
import com.gateway.filter.AiChatTokenAuthenticationFilter;
import com.gateway.filter.SecurityTokenAuthenticationWebFilter;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsConfigurationSource;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;

import java.util.Arrays;

@Configuration
@EnableWebFluxSecurity
public class SecurityConfiguration {

    @Resource
    SecurityProperties securityProperties;

    @Bean
    public SecurityWebFilterChain webFilterChain(ServerHttpSecurity serverHttpSecurity) throws Exception {
        serverHttpSecurity
                .authorizeExchange(exchanges -> {
                    // 配置放行白名单
                    for (String url : securityProperties.getExclude_url()) {
                        exchanges.pathMatchers(url).permitAll();
                    }
                    // 剩余请求全部拦截 需要登入后才可访问
                    exchanges.anyExchange().authenticated();
                })
                .formLogin(ServerHttpSecurity.FormLoginSpec::disable)  // 禁用表单登入
                .logout(ServerHttpSecurity.LogoutSpec::disable)        // 禁用原始登出
                .csrf(ServerHttpSecurity.CsrfSpec::disable)            // 禁用csrf
                .cors(cors -> cors.configurationSource(corsConfigurationSource())) // 应用CORS策略
                .addFilterBefore(aiChatTokenAuthenticationFilter(), SecurityWebFiltersOrder.AUTHENTICATION)    // 添加自定义过滤器 在 AUTHENTICATION 认证过滤器之前
                .addFilterBefore(securityTokenAuthenticationWebFilter(), SecurityWebFiltersOrder.AUTHENTICATION);    // 添加自定义过滤器 在 AUTHENTICATION 认证过滤器之前
        return serverHttpSecurity.build();
    }

    /**
     * 配置跨域问题
     */
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOriginPatterns(Arrays.asList("*")); // 允许的源
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); // 允许的方法
        configuration.setAllowedHeaders(Arrays.asList("*")); // 允许的头
        configuration.setAllowCredentials(true); // 允许携带凭证
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration); // 对所有路径应用配置
        return source;
    }

    /**
     * token 认证过滤器
     */
    @Bean
    public SecurityTokenAuthenticationWebFilter securityTokenAuthenticationWebFilter(){
        return new SecurityTokenAuthenticationWebFilter();
    }

    @Bean
    public AiChatTokenAuthenticationFilter aiChatTokenAuthenticationFilter(){
        return new AiChatTokenAuthenticationFilter();
    }


}
